package com.ktwlsoft.archivemanage.domain.business.businessService;

import com.github.pagehelper.PageInfo;
import com.ktwlsoft.archivemanage.domain.business.repositoryService.ImgsService;
import com.ktwlsoft.archivemanage.domain.business.repositoryService.businessInspect.BusinessInspectRepositoryService;
import com.ktwlsoft.archivemanage.domain.business.repositoryService.mend.MendListOptLogRepositoryService;
import com.ktwlsoft.archivemanage.domain.business.repositoryService.mend.MendListRepositoryService;
import com.ktwlsoft.archivemanage.domain.business.repositoryService.mend.MendSubjectOptionRepositoryService;
import com.ktwlsoft.archivemanage.domain.business.repositoryService.mend.MendSubjectRepositoryService;
import com.ktwlsoft.archivemanage.domain.business.repositoryService.NotifySetRepositoryService;
import com.ktwlsoft.archivemanage.domain.dao.entity.Account;
import com.ktwlsoft.archivemanage.domain.dao.entity.Imgs;
import com.ktwlsoft.archivemanage.domain.dao.entity.NotifySet;
import com.ktwlsoft.archivemanage.domain.dao.entity.mend.MendList;
import com.ktwlsoft.archivemanage.domain.dao.entity.mend.MendListOptLog;
import com.ktwlsoft.archivemanage.domain.dao.entity.mend.MendSubject;
import com.ktwlsoft.archivemanage.domain.dao.entity.mend.MendSubjectOption;
import com.ktwlsoft.archivemanage.payload.exception.BusinessException;
import com.ktwlsoft.archivemanage.payload.mendList.*;
import com.ktwlsoft.archivemanage.service.security.UserPrincipal;
import lombok.Getter;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.validation.constraints.NotNull;
import java.util.List;

@Service
public class MendListService {

    private final MendListRepositoryService mendListRepositoryService;

    private final MendSubjectRepositoryService mendSubjectRepositoryService;

    private final MendSubjectOptionRepositoryService mendSubjectOptionRepositoryService;

    private final NotifySetRepositoryService notifySetRepositoryService;

    private final MendListOptLogRepositoryService mendListOptLogRepositoryService;

    private final BusinessInspectRepositoryService businessInspectRepositoryService;

    private final NotifyMessageScheduleTask notifyMessageScheduleTask;

    @Getter
    private final ImgsService imgsService;

    public MendListService(MendListRepositoryService mendListRepositoryService, MendSubjectRepositoryService mendSubjectRepositoryService, MendSubjectOptionRepositoryService mendSubjectOptionRepositoryService, ImgUploadService imgUploadService, NotifySetRepositoryService notifySetRepositoryService, MendListOptLogRepositoryService mendListOptLogRepositoryService, BusinessInspectRepositoryService businessInspectRepositoryService, NotifyMessageScheduleTask notifyMessageScheduleTask, ImgsService imgsService) {
        this.mendListRepositoryService = mendListRepositoryService;
        this.mendSubjectRepositoryService = mendSubjectRepositoryService;
        this.mendSubjectOptionRepositoryService = mendSubjectOptionRepositoryService;
        this.notifySetRepositoryService = notifySetRepositoryService;
        this.mendListOptLogRepositoryService = mendListOptLogRepositoryService;
        this.businessInspectRepositoryService = businessInspectRepositoryService;
        this.notifyMessageScheduleTask = notifyMessageScheduleTask;
        this.imgsService = imgsService;
    }

    /**
     * 生成整改单
     *
     * @param mendList
     */
    @Transactional(rollbackFor = Exception.class)
    public void insertMendList(MendList mendList) {
        mendListOptLogRepositoryService.insert(mendList.getId(), MendListOptLog.OperationType.GENERATE);
        mendList.setMendMark(mendList.getMark());
        mendListRepositoryService.generateMendList(mendList);
        for (MendSubject subject : mendList.getSubjects()) {
            subject.setMendMark(subject.getDefaultMark());
            mendSubjectRepositoryService.save(subject);
            for (MendSubjectOption option : subject.getSubjectOptionList()) {
                mendSubjectOptionRepositoryService.save(option);
            }
        }
        notifyMessageScheduleTask.newMendNotifyMessage(mendList.getId(), mendList.getMark(), mendList.getFullMark(), mendList.getGuidNum(), mendList.getArchivist(), mendList.getArchivistId(),
                mendList.getInstructor(), mendList.getInstructorId(),mendList.getInspectId());
    }

    /**
     * 上传整改图片和添加整改说明，MendList修改整改后得分，整改备注、整改说明
     *
     * @param request
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public void modifyMendList(MendListModifyRequest request) {
        mendListOptLogRepositoryService.insert(request.getId(), MendListOptLog.OperationType.MEND_COMMIT);
        mendListRepositoryService.updateMendList(request.getId(), request.getMendRemark(), request.getVerifyRemark());
        mendSubjectRepositoryService.updateMendSubject(request.getSubjects());
        notifyMessageScheduleTask.addMendListWeb(request);
    }

    @Transactional(rollbackFor = Exception.class)
    public void verifyMend(MendVerifyRequest request) {
        if (request.getPass()) {
            mendListRepositoryService.verifyMend(request.getMendId(), MendList.MendState.VERIFY_PASS, request.getMendAdvice(), request.getMendMark());
            mendListOptLogRepositoryService.insert(request.getMendId(), MendListOptLog.OperationType.PASS);
            for (MendVerifySubject subject : request.getSubjects()) {
                mendSubjectRepositoryService.verify(subject);
                mendSubjectOptionRepositoryService.verifyUncheckAll(subject.getMendSubjectId());
                for (MendVerifySubjectOption option : subject.getOptions()) {
                    mendSubjectOptionRepositoryService.verify(option);
                }
            }
        } else {
            mendListRepositoryService.verifyMend(request.getMendId(), MendList.MendState.REPULSE_MEND, request.getMendAdvice(), request.getMendMark());
            mendListOptLogRepositoryService.insert(request.getMendId(), MendListOptLog.OperationType.REFUSE);
            for (MendVerifySubject subject : request.getSubjects()) {
                mendSubjectRepositoryService.verify(subject);
                mendSubjectOptionRepositoryService.verifyUncheckAll(subject.getMendSubjectId());
                for (MendVerifySubjectOption option : subject.getOptions()) {
                    mendSubjectOptionRepositoryService.verify(option);
                }
            }
        }
    }

    /**
     * 删除所有整改单上下游数据
     *
     * @param mendId 整改单id
     */
    @Transactional(rollbackFor = Exception.class)
    public void deleteMend(Long mendId) {
        mendListRepositoryService.delete(mendId);
        List<MendSubject> subjects = mendSubjectRepositoryService.findByMendId(mendId);
        for (MendSubject mendSubject : subjects) {
            mendSubjectRepositoryService.delete(mendSubject.getId());
            List<MendSubjectOption> mendSubjectOptions = mendSubjectOptionRepositoryService.getMendSubjectOptionMapper().selectByBusinessId(mendSubject.getId());
            for (MendSubjectOption mendSubjectOption : mendSubjectOptions) {
                ImgUploadService.deleteByBusinessId(mendSubjectOption.getId());
            }
            mendSubjectOptionRepositoryService.delete(mendSubject.getId());
        }
    }

    @Transactional(rollbackFor = Exception.class)
    public void setNotifySet(NotifySetRequest request) {
        NotifySet notifySet = notifySetRepositoryService.findByName("MEND_WARNING");
        if (notifySet == null) {
            throw new BusinessException("未找到“业务整改”通知设定，请确认数据库中有默认数据");
        }
        notifySet.setNotifyPeriod(request.getPeriod());
        notifySet.setNotifyPeriodUnit(request.getUnit());
        notifySetRepositoryService.updateSet(notifySet);
    }

    public PageInfo<MendListOptLog> findLogByPage(Integer pn, Integer pageSize, @NotNull Long mendId) {
        return mendListOptLogRepositoryService.findByPage(pn, pageSize, mendId);
    }

    public List<InstructorsResponse> wxGetInstructors() {
        Account account = UserPrincipal.getCurrentUser();
        return mendListRepositoryService.getInstructorsByArchivistId(account != null ? account.getId() : null);
    }
}
